Skip to content

Nginx使用

1、启动Nginx

Windows 下启动 nginx

在下载 nginx 后,在nginx安装目录的绝对路径的框框内输入 cmd

直接输入 nginx 或者 start nginx,然后回车,就可以启动nginx

nginx
#推荐这一种
start nginx

在浏览器地址栏输入 localhost:80,然后再回车, 查看是否有 nginx 访问主页,如果有,则启动成功。

一般访问问题是端口占用,可以改一下 nginx 访问端口,或者杀掉对应进程。

关闭nginx的命令:

#快速关闭
nginx -s stop
#优雅关闭
nginx -s quit

重新加载

nginx -s reload

一般来说,启动 nginx 后会出现两个或两个以上的线程,其中 1 个是主线程,另外 n 个是工作进程。(通过使用多个工作进程来并行处理请求,从而实现高性能和高并发处理能力)

默认情况下,Nginx可能会根据你的服务器的CPU核心数自动设置工作进程的数量,以最大化利用硬件资源。

如何区分,一般在 windows 环境下,PID 较小的那个是先启动的(PID较小的那个进程通常是首先启动的进程,也就是主进程。)

tasklist /fi "IMAGENAME eq nginx.exe,可以通过这个命令或者在任务管理器上看对应的线程信息

linux 环境下,可以通过 ps aux | grep nginx 查看进程信息

会有类似输出

root     12345  0.0  0.1  123456  7890 ?        Ss   Apr10   0:00 nginx: master process /usr/sbin/nginx -g daemon off;
nginx    12346  0.0  0.2  123457  7891 ?        S    Apr10   0:00 nginx: worker process

通过 nginx 访问服务器文件(预览)

这里演示操作是在 docker 容器中进行的,在容器内部,Nginx的配置文件,通常位于/etc/nginx/nginx.conf/etc/nginx/conf.d/目录下。

vi /etc/nginx/nginx.conf

###修改后重新加载
nginx -s reload

实际操作这里 vi 显示不存在命令,看了一下建议:对于生产环境的容器,直接进入容器修改配置文件并不是最佳实践。最好是通过更新配置文件和重新部署容器的方式来管理更改

看了一下 Portainer 工具中里面是写了映射路径的,根据提示找到配置文件:/home/nginx/conf/nginx.conf

image.png

修改配置文件

配置一个新的server块或修改现有的server块,以指向你的文件存储目录。

server {
    listen 80;
    192.168.0.21; # 替换为你的域名或IP地址

    location /files {
        alias /root/wJF/shareFiles/; # 指向实际的文件目录
        autoindex on; # 开启目录列表
    }
}

重启容器

访问:http://192.168.0.21/files

修正:

启动命令的原因,然后由于是 Docker 容器内,需要挂载路径,需要改一下配置文件和启动命令

	server {
		listen 80;
		server_name 192.168.0.21; # 替换为你的域名或IP地址

		location /files { 
			alias /usr/share/nginx/shareFile/; # 指向实际的文件目录
			autoindex on; # 开启目录列表
		}
	}

启动命令

docker run \
-p 9002:80 \
--name nginx \
-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /home/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /home/nginx/log:/var/log/nginx \
-v /home/nginx/html:/usr/share/nginx/html \
-v /home/nginx/shareFile/:/usr/share/nginx/shareFile \
-v /home/nginx/ssl:/etc/nginx/ssl \
-d nginx:latest

访问: http://192.168.0.21:9002/files/


docker 容器内访问有点问题,改为在 windows 本地环境下操作

修改配置文件

	server {
		listen 8087;
		server_name localhost; # 替换为你的域名或IP地址

		location /files {
			alias D:/01_LQ/DiaryLearn/Java/Nginx/test/; # 指向实际的文件目录
			autoindex on; # 开启目录列表
		}
	}

同端口 80 关闭一下,正常访问 http://localhost:8087/files 能够显示对应文件,文件名不要是中文的,支持 pdf 预览和下载操作。


从目标服务器下载文件

经过上面的配置后,你能够在浏览器进行访问相关文件夹的内容,如果你需要下载,可以通过下面操作:

示例:

curl -O 192.168.0.21:9002/files/MQ.pdf

wget 192.168.0.21:9002/files/MQ.pdf (Liinux)

上传文件操作

做一个简易的反向代理就行,后端服务可以使用 Java 的程序或者其他的

看了一下相关的操作说明,一般都是 通过代理操作来进行文件上传操作的,然后在文件上传过程中,对于 nginx 的配置是有一些配置项配置的。

了解一些关于大文件传输时可能会用的配置项:

配置项描述
client_max_body_size设置请求体允许最大体积
client_header_timeout等待客户端发送一个请求头的超时时间
client_body_timeout设置读取请求体的超时时间
proxy_read_timeout设置请求被后端服务器读取时,Nginx等待的最长时间
proxy_send_timeout设置

在传输大文件时,client_max_body_sizeclient_header_timeoutproxy_read_timeoutproxy_send_timeout这四个参数值都可以根据自己项目的实际情况来配置。

实际操作进行的配置

nginx.conf

	server {
		listen 8087;
		server_name localhost; # 替换为你的域名或IP地址 

		location /files {
			alias D:/01_LQ/DiaryLearn/Java/Nginx/test/download/; # 指向实际的文件目录
			autoindex on; # 开启目录列表
		}
		
		location /upload {
			#指定客户端请求体的临时存储路径。如果客户端上传的数据非常大,不能一次性读入内存,Nginx会将接收到的数据流分块写入这个临时文件夹。
			client_body_temp_path D:/01_LQ/DiaryLearn/Java/Nginx/test/uploads/1/;
			#设置客户端请求体的大小限制为5MB。如果请求体的大小超过这个值,客户端会收到一个表示请求实体过大的413错误。
			client_max_body_size 5m;
			proxy_set_header Host $http_host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			#所有匹配/upload的请求将被转发到本机的8080端口的HTTP服务器。这意味着实际处理文件上传的是监听在8080端口的服务器。
			proxy_pass http://localhost:8080/system/file/upload;
			error_page   500 502 503 504  /50x.html;
		}
	}

java 的后端代码示例

@RestController  
@RequestMapping("/system/file")  
public class FileUploadController {  
  
    @PostMapping("/upload")  
    public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {  
        String message = "";  
        try {  
            // 目标目录路径字符串  
            String directory = "D:/01_LQ/DiaryLearn/Java/Nginx/test/uploads/2/";  
            // 通过Paths.get()转换为Path对象  
            Path path = Paths.get(directory);  
            // 确保目录存在  
            Files.createDirectories(path);  
            // 解析路径与文件原始名称组合为新路径  
            Path filePath = path.resolve(file.getOriginalFilename());  
            // 保存文件  
            Files.copy(file.getInputStream(), filePath);  
  
            message = "You successfully uploaded " + file.getOriginalFilename() + "!";  
            return ResponseEntity.status(200).body(message);  
        } catch (Exception e) {  
            message = "Failed to upload " + file.getOriginalFilename() + " due to " + e.getMessage();  
            return ResponseEntity.status(500).body(message);  
        }  
    }  
}

配置头相关的内容注意一下。

这里改善一下上述的 java 文件传输代码

@PostMapping("/upload")  
public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {  
    String message = "";  
    if (file.isEmpty()) {  
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("The file is empty.");  
    }  
  
    // 目标目录路径字符串  
    String directory = "D:/01_LQ/DiaryLearn/Java/Nginx/test/uploads/2/";  
    // 通过Paths.get()转换为Path对象  
    Path path = Paths.get(directory);  
  
    try {  
        // 确保目录存在  
        Files.createDirectories(path);  
  
        // 解析路径与文件原始名称组合为新路径  
        Path filePath = path.resolve(file.getOriginalFilename());  
  
        // 检查文件是否已存在  
        if (Files.exists(filePath)) {  
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("File already exists: " + file.getOriginalFilename());  
        }  
  
        // 保存文件  
        try (InputStream inputStream = file.getInputStream()) {  
            Files.copy(inputStream, filePath);  
        }  
  
        message = "2 You successfully uploaded " + file.getOriginalFilename() + "!";  
        return ResponseEntity.status(HttpStatus.OK).body(message);  
    } catch (IOException e) {  
        message = "Failed to upload " + file.getOriginalFilename() + " due to " + e.getMessage();  
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(message);  
    }  
}

这里主要的区别是添加了 try-with-resources (注意添加一下)

try-with-resources语句可以自动管理资源,确保在语句结束时自动关闭资源,这对于文件上传中的输入流非常有用。

文件传输

nginx 应该不支持文件传输,需要使用第三方组件进行文件传输,比如 sftp 等。


参考